package com.crt.nexus.oauth.advice;

import com.crt.nexus.core.response.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.jwt.BadJwtException;
import org.springframework.web.bind.UnsatisfiedServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import static com.crt.nexus.core.constant.SecurityConstants.GRANT;

@Slf4j
@RestControllerAdvice
public class OauthExceptionHandler {

    @ExceptionHandler(AccessDeniedException.class)
    @ResponseStatus(HttpStatus.FORBIDDEN)
    public ResponseEntity<R<?>> handleAccessDeniedException(AccessDeniedException e) {
        log.error("访问拒绝: {}", e.getLocalizedMessage());
        return ResponseEntity.status(HttpStatus.FORBIDDEN).body(R.failed(e.getMessage()));
    }

    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ResponseEntity<R<?>> handleAuthenticationException(AuthenticationException e) {
        log.error("认证失败: {}", e.getMessage());
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(R.failed(e.getMessage()));
    }

    @ExceptionHandler(DisabledException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public ResponseEntity<R<?>> handleDisabledException(DisabledException e) {
        log.error("帐号禁用: {}", e.getMessage());
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(R.failed(e.getMessage()));
    }

    @ExceptionHandler(UnsatisfiedServletRequestParameterException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<R<?>> handleUnsatisfiedServletRequestParameterException(UnsatisfiedServletRequestParameterException e) {
        log.error("参数错误: {}", e.getMessage());
        String msg = e.getMessage();
        if (e.getMessage() != null && e.getMessage().contains(GRANT)) {
            msg = "未知的客户端授权类型";
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(R.failed(msg));
    }

    @ExceptionHandler(BadJwtException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<R<?>> handleBadJwtException(BadJwtException e) {
        log.error("JWT错误: {}", e.getMessage());
        String msg = e.getMessage();
        if (e.getMessage() != null) {
            if (e.getMessage().contains("Invalid signature")) {
                msg = "无效的令牌签名";
            } else if (e.getMessage().contains("Missing dot delimiter(s)")) {
                msg = "未知的令牌";
            } else if (e.getMessage().contains("Jwt expired")) {
                msg = "令牌已过期";
            }
        }
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(R.failed(msg));
    }

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<R<?>> handleGlobalException(Exception e) {
        log.error("系统异常: {}", e.getMessage(), e);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(R.failed(e.getMessage()));
    }

}
